﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Windows;

namespace LEShortcut.Helper
{
    /// <summary>
    ///     Provide functions of globalization
    /// </summary>
    internal static class I18NHelper
    {
        /// <summary>
        ///     Build a culture resouce dictionary from current assembly
        /// </summary>
        /// <param name="lanDictionary">Culture resouce dictionary to build</param>
        /// <param name="relativePath"><b>Lower case</b> relative path of the culture resources</param>
        /// <returns></returns>
        internal static bool GetGlobalResourcesDictionary(Dictionary<int, string> lanDictionary,
            string relativePath)
        {
            try
            {
                Assembly assembly = Assembly.GetExecutingAssembly();
                Stream stream =
                    assembly.GetManifestResourceStream(string.Concat(assembly.GetName().Name, ".g.resources"));
                if (stream != null)
                {
                    using (var rr = new ResourceReader(stream))
                    {
                        foreach (DictionaryEntry entry in rr)
                        {
                            var path = (string) entry.Key;
                            if (path.StartsWith(relativePath))
                                lanDictionary.Add(new CultureInfo(Path.GetFileNameWithoutExtension(path)).LCID,
                                    path.Replace("baml", "xaml"));
                        }
                    }
                    stream.Dispose();
                }
            }
            catch
            {
                return false;
            }
            return true;
        }

        /// <summary>
        ///     Load specify culture resouce
        /// </summary>
        /// <param name="lanDictionary">Culture resouce dictionary</param>
        /// <param name="oldId">Instance culture LCID</param>
        /// <param name="newId">Culture to load</param>
        /// <returns></returns>
        internal static bool LoadCultureResouce(Dictionary<int, string> lanDictionary, int oldId, int newId)
        {
            if (oldId == newId) return true;
            try
            {
                if (lanDictionary.ContainsKey(newId) && lanDictionary.ContainsKey(oldId))
                {
                    int index = -1;
                    Collection<ResourceDictionary> mergedDictionaries =
                        Application.Current.Resources.MergedDictionaries;
                    for (int i = 0; i < mergedDictionaries.Count; i++)
                    {
                        if (Path.GetFileNameWithoutExtension(mergedDictionaries[i].Source.ToString()) ==
                            Path.GetFileNameWithoutExtension(lanDictionary[oldId]))
                        {
                            index = i;
                            break;
                        }
                    }
                    if (index < 0) return false;
                    var resourceDictionary = new ResourceDictionary
                    {
                        Source = new Uri(lanDictionary[newId], UriKind.Relative)
                    };
                    mergedDictionaries.RemoveAt(index);
                    mergedDictionaries.Add(resourceDictionary);
                }
            }
            catch
            {
                return false;
            }
            return true;
        }

        internal static T GetI18NResource<T>(this string key) where T : class
        {
            return Application.Current.TryFindResource(key) as T;
        }

        internal static string GetI18NString(this string key)
        {
            return key.GetI18NResource<string>().Replace("[br]", "\n");
        }
    }
}